package com.neu.controller;

import cn.hutool.core.bean.BeanUtil;
import com.neu.base.PageBean;
import com.neu.base.Result;
import com.neu.entity.*;
import com.neu.entity.DTO.InviteUserRequest;
import com.neu.entity.DTO.RemoveUserDTO;
import com.neu.entity.DTO.TaskDTO;
import com.neu.entity.security.LoginUser;
import com.neu.service.TaskService;
import com.neu.utils.excel.ExcelUtil;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Parameters;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.web.bind.annotation.*;

import java.time.LocalDateTime;
import java.util.List;
import javax.servlet.http.HttpServletResponse;
import java.util.Map;
import java.util.UUID;

@RestController
@RequestMapping("/tasks")
@Tag(name = "任务管理")
public class TaskController {
    @Autowired
    TaskService taskService;



    @PostMapping("/page")
    @Parameters({
            @Parameter(name = "pageNum", description = "页码", required = true),
            @Parameter(name = "pageSize", description = "每页显示数量", required = true)
    })
    @Operation(summary = "分页查询")
    public Result page(@RequestParam Integer pageNum,
                       @RequestParam Integer pageSize) {
        //注意这里向前端传递DTO对象,DTO对实体类进行了封装，给前端提供更多的数据
        // 后续进行数据库操作时通过BeanUtil.copyProperties(dto,entity)进行转换成entity对象
        PageBean<TaskDTO> pagelist = taskService.pagelist(pageNum, pageSize);
        //如果当前页码值大于总页数，返回最后一页数据
        if (pageNum > pagelist.getTotalPage()) {
            pagelist = taskService.pagelist((int) pagelist.getTotalPage(), pageSize);
        }
        return Result.success(pagelist);
    }

    @PostMapping("/search")
    @Operation(summary = "搜索任务")
    public Result search(
            @RequestBody Map map) {
        PageBean<TaskDTO> pagelist = taskService.search(map);
        return Result.success(pagelist);
    }

    @PostMapping("/findUserTaskByProjectId")
    @Operation(summary = "根据任务id查询任务DTO")
    public Result findUserByProjectId(@RequestBody Map<String, String> map) {
        String taskId = map.get("taskId");
        TaskDTO dto = taskService.findUserTaskByProjectId(taskId);
        return Result.success(dto);

    }



    @PostMapping("/inviteUserInEdit")
    @Operation(summary = "在编辑任务界面邀请用户")//相当于新增任务了
    public Result inviteUserInEdit(@RequestBody InviteUserRequest inviteUserRequest) {
        //Spring MVC 在一个请求中只能解析一个请求体（即一个 @RequestBody）
        TaskDTO taskDTO = inviteUserRequest.getTaskDTO();
        Role role = inviteUserRequest.getRole();
        User user = inviteUserRequest.getUser();
        return taskService.inviteUserInEdit(taskDTO, role, user);
    }

    @PostMapping("/update")
    @Operation(summary = "更新任务信息，不包含进度")
    public Result update(@RequestBody TaskDTO taskDTO) {
        Task task = new Task();
        BeanUtil.copyProperties(taskDTO, task);
        task.setTaskId(taskDTO.getTaskId());
        return Result.success(taskService.updateById(task));
    }

    @PostMapping("/removeUserTask")
    @Operation(summary = "移除某个任务下的用户")
    public Result removeUserTask(@RequestBody RemoveUserDTO removeUserDTO) {

        //嵌套的对象（如 taskDTO）会被解析为 LinkedHashMap。
        //方法一：定义一个专门的请求 DTO 类，包含 TaskDTO 和 userId 字段。这样，Spring 会自动将 JSON 映射到相应的对象中，避免类型转换问题。
        //方法二：手动将嵌套的 LinkedHashMap 转换为 TaskDTO。
        /*ObjectMapper mapper = new ObjectMapper();
        TaskDTO taskDTO = mapper.convertValue(map.get("taskDTO"), TaskDTO.class);
        String userId = (String)map.get("userId");*/

        TaskDTO taskDTO = removeUserDTO.getTaskDTO();
        //判断当前用户是否是任务负责人
        LoginUser loginUser = (LoginUser) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        if (!taskDTO.getAssignedTo().equals(loginUser.getUserId())) {
            return Result.error("只有任务负责人才能移除用户！");
        }
        String userId = removeUserDTO.getUserId();
        boolean flag = taskService.removeUserTask(taskDTO, userId);
        if (!flag) {
            return Result.error("不能移除任务负责人！");
        }
        return Result.success();
    }

    @PostMapping("/delete")
    @Operation(summary = "删除任务")
    public Result delete(@RequestBody TaskDTO taskDTO) {

        return taskService.delete(taskDTO);
    }

    @PostMapping("/getPreTask")
    @Operation(summary = "获取前置任务")
    public Result getPreTask(@RequestBody TaskDTO taskDTO) {
        return Result.success(taskService.getPreTask(taskDTO));
    }

    @PostMapping("/findById")
    @Operation(summary = "根据任务id获取任务")
    public Result findById(@RequestBody TaskDTO taskDTO) {
        return Result.success(taskService.findById(taskDTO));
    }

    @GetMapping("/export")
    @Operation(summary = "导出任务信息")
    public void export(HttpServletResponse response) {
        LoginUser loginUser = (LoginUser) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        List<String> permissions = loginUser.getAuthorityStrings();
        String fileName = "";
        if (!permissions.contains("ROLE_super")) {
            fileName = loginUser.getTenantName() + "任务信息表.xlsx";// 下载时的文件名
        } else {
            fileName = "swpt所有任务信息表.xlsx";// 下载时的文件名
        }
        String sheetName = "任务信息"; // 工作表名称
        List<Task> tasks = taskService.all();
        // 调用工具类进行导出
        ExcelUtil.exportExcel(response, fileName, sheetName, Task.class, tasks);
    }

    @PostMapping("/idTypeSort")
    @Operation(summary = "菏泽爷说的分页分类")
    public Result sortByUIdAndType(@RequestBody Map<String, String> map) {
        //update
        String userId = map.get("userId");
        String taskType = map.get("taskType");
        String pageIdx = map.get("pageIdx");
        String pageSize = map.get("pageSize");
        List<Task> tasks = taskService.sortByUIdAndType(userId, taskType, pageIdx, pageSize);
//        TaskDTO dto = taskService.findUserTaskByProjectId(taskId);
        if (!tasks.isEmpty()) {
            return Result.success(tasks);
        }
        return Result.error("目标分类无数据");
    }

    @GetMapping("/allForFp")
    @Operation(summary = "获取功能点评估任务")
    public Result allForFp() {

        List<Task> tasks = taskService.allForFp();
        return Result.success(tasks);
    }

}
